package com.wxxymaker.edu.service;

import com.blade.ioc.annotation.Bean;
import com.blade.ioc.annotation.Inject;
import com.blade.kit.CollectionKit;
import com.blade.kit.StringKit;
import com.wxxymaker.edu.model.entity.Practice;
import com.wxxymaker.edu.model.entity.PracticeOption;
import com.wxxymaker.edu.model.entity.Task;
import com.wxxymaker.edu.utils.HttpUtil;
import com.wxxymaker.edu.utils.TimeUtils;
import io.github.biezhi.anima.Anima;
import io.github.biezhi.anima.core.AnimaQuery;
import io.github.biezhi.anima.core.Joins;
import io.github.biezhi.anima.enums.OrderBy;
import io.github.biezhi.anima.page.Page;

import java.util.List;

/**
 * @AUTHOR soft
 * @DATE 2018/10/13 15:40
 * @DESCRIBE
 */
@Bean
public class PracticeService implements Service<Practice> {
    @Inject
    private PracticeOptionService optionService;

    @Inject
    private PracticeResponseService responseService;

    public Page<Practice> pageGroup(int kid, int page, int size) {
        Page<Practice> page1 = Anima.select().from(Practice.class)
                .join(Joins.with(Task.class)
                        .as(Practice::getTask)
                        .on(Practice::getTaskId, Task::getId))
                .where("course_id=" + kid + " group by task_id")
                .page(page, size);
        if (CollectionKit.isNotEmpty(page1.getRows())) {
            Page<Practice> objectPage = new Page<Practice>(page1.getRows().size(), 1, 10);
            objectPage.setRows(page1.getRows());
            return objectPage;
        }
        return null;
    }

    public Page<Practice> page(int kid, Integer tid, int page, int size) {
        AnimaQuery<Practice> query = Anima.select().from(Practice.class)
                .where(Practice::getCourseId, kid)
                .join(Joins.with(PracticeOption.class)
                        .as(Practice::getOptions)
                        .on(Practice::getId, PracticeOption::getPracticeId))
                .order(Practice::getTime, OrderBy.DESC);
        if (tid!=null) query.where(Practice::getTaskId, tid);
        Page<Practice> page1 = query.page(page, size);
        return HttpUtil.returnPage(page1);
    }

    public Page<Practice> page(int kid, Integer tid, Integer type, String keyWord, int page, int size) {
        AnimaQuery<Practice> query = Anima.select().from(Practice.class)
                .where(Practice::getCourseId, kid)
                .join(Joins.with(Task.class)
                        .as(Practice::getTask)
                        .on(Practice::getTaskId, Task::getId))
                .join(Joins.with(PracticeOption.class)
                        .as(Practice::getOptions)
                        .on(Practice::getId, PracticeOption::getPracticeId))
                .order(Practice::getTime, OrderBy.DESC);
        if (null != tid && tid > 0) query.where(Practice::getTaskId, tid);
        if (null != type && type >= 0) query.where(Practice::getType, type);
        if (StringKit.isNotEmpty(keyWord)) query.like(Practice::getStem, "%"+keyWord+"%");
        Page<Practice> page1 = query.page(page, size);
        return HttpUtil.returnPage(page1);
    }

    public Practice addJoinResult(Practice practice, List<PracticeOption> options) {
        Practice add = this.add(practice);
        if (add!=null) {
            List<PracticeOption> resultList = optionService.addAll(options, add.getId());
            if (CollectionKit.isNotEmpty(resultList)) {
               add.setOptions(options);
               return practice;
            }
        }
        return null;
    }

    @Override
    public Practice add(Practice practice) {
        practice.setTime(TimeUtils.getTime());
        Integer integer = practice.save().asInt();
        if (integer>0) {
            practice.setId(integer);
            return practice;
        }
        return null;
    }

    @Override
    public Practice delete(Object pk) {
        Practice practice = byId(pk);
        if (practice!=null) {
            practice.delete();
            optionService.deleteByPid((Integer) pk);
            return practice;
        }
        return null;
    }

    @Override
    public boolean change(Practice practice) {
        if (practice.getId() > 0) {
            return practice.update() > 0;
        }
        return false;
    }

    @Override
    public Practice byId(Object pk) {
        return findOne((Integer) pk, false);
    }

    public Practice findOne(Integer id, boolean joinOptions) {
        AnimaQuery<Practice> from = Anima.select().from(Practice.class);
        if (joinOptions) from.join(Joins.with(PracticeOption.class)
                .as(Practice::getOptions)
                .on(Practice::getId, PracticeOption::getPracticeId));
        return from.byId(id);
    }

    public long countBykId(Integer kid) {
        return Anima.select().from(Practice.class).where(Practice::getCourseId, kid).count();
    }

    public long countByUid(Integer uid) {
        String sql = "select count(*) as taskNum from practice where course_id in " +
                "(select id from course where user_id = ?)";
        return Anima.select().bySQL(Long.class, sql, uid).one();
    }

    public int deleteByKid(Integer kid) {
        List<Practice> list = Anima.select().from(Practice.class).where(Practice::getCourseId, kid).all();
        if (CollectionKit.isNotEmpty(list)) {
            for (Practice practice : list) {
                practice.delete();
                optionService.deleteByPid(practice.getId());
                responseService.deleteByPid(practice.getId());
            }
            return list.size();
        }
        return 0;
    }
}
